package limiter

import (
	"context"
	_ "embed"
	"github.com/redis/go-redis/v9"
	"time"
)

//go:embed slide_window.lua
var luaScript string

// RedisSlidingWindowLimiter 限流器接口的redis实现
type RedisSlidingWindowLimiter struct {
	cmd      redis.Cmdable
	interval time.Duration
	// 阈值
	rate int
}

func NewRedisSlidingWindowLimiter(cmd redis.Cmdable, interval time.Duration, rate int) *RedisSlidingWindowLimiter {
	return &RedisSlidingWindowLimiter{
		cmd:      cmd,
		interval: interval,
		rate:     rate,
	}
}

func (b *RedisSlidingWindowLimiter) Limit(ctx context.Context, key string) (bool, error) {
	// 调用 slide_window.lua 脚本
	return b.cmd.Eval(ctx, luaScript,
		//限流对象  对应脚本里的   local key = KEYS[1]
		[]string{key},
		// 窗口大小  对应脚本里的  local window = tonumber(ARGV[1])
		b.interval.Milliseconds(),
		// 限流阈值  对应脚本里的  local threshold = tonumber( ARGV[2])
		b.rate,
		// 当前的时间戳   对应脚本里的 tonumber(ARGV[3])
		time.Now().UnixMilli()).Bool() // Bool 执行lua脚本返回的结果 返回的是 bool 和 error
}
